package thread.alternate_print;

/**
 * 通过 synchronized + Object.wait()和 Object.notifyAll() 来控制线程的运行，缺点是不能精准控制，每次唤醒都会产生惊群效应
 * @program: rocsun
 * @description:
 * @author: yx.guo
 * @create: 2025-08-02 09:39
 **/
public class SyncWaitNotify {
    // 计数器,从1开始
    private int count = 1;
    // 最大打印数
    private static final int MAX = 100;
    // 锁
    private final Object lock = new Object();
    // 线程数
    private final int threadCount;

    public SyncWaitNotify(int threadCount) {
        this.threadCount = threadCount;
    }

    public void print(int threadIndex) {
        while (true) {
            // 加锁,由于是公共方法，所以使用同一把锁 lock
            synchronized (lock) {
                // 这里一定要使用 (count - 1) % threadCount != threadIndex 来判断，才会保证 题目要求
                while ((count - 1) % threadCount != threadIndex) {
                    if (count > MAX) return;
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        return;
                    }
                }

                if (count > MAX) {
                    lock.notifyAll();
                    return;
                }

                System.out.println(Thread.currentThread().getName() + "-" + count++);
                lock.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        int threadCount = 2;
        SyncWaitNotify syncWaitNotify = new SyncWaitNotify(threadCount);
        for (int i = 0; i < threadCount; i++) {
            final int threadIndex = i;
            new Thread(() -> syncWaitNotify.print(threadIndex), "t" + (i + 1)).start();
        }
    }
}
